#include"work_thread.h"
#include<sys/wait.h>
#include<fcntl.h>
#define max_arg 10

char* get_cmd(char *p,char *myargv[])
{
    if(p==NULL||myargv==NULL)
    {
        return NULL;
    }

    char *s=NULL;
    int i=0;
    char *q=strtok_r(p," ",&s);
    while(q!=NULL)
    {
        myargv[i++]=q;
        q=strtok_r(NULL," ",&s);
    }

    return myargv[0];
}

void send_file(int c,char *name)
{
    if(name==NULL)
    {
        send(c,"err",3,0);
        return;
    }

    int fd=open(name,O_RDONLY);
    if(fd==-1)
    {
        send(c,"err",3,0);
        return;
    }
    
    int n=lseek(fd,0,SEEK_END);
    lseek(fd,0,SEEK_SET);
    char buff[128]={0};
    sprintf(buff,"ok#%d",n);
    send(c,buff,strlen(buff),0);


    memset(buff,0,128);
    int m=recv(c,buff,127,0);
    if(m<=0)
    {
        close(fd);
        return ;
    }
    
    if(strcmp(buff,"ok")!=0)
    {
        close(fd);
        return;
    }


    char data[1024]={0};

    int num=0;
    while((num=read(fd,data,1024))>0)
    {
        send(c,data,num,0);

    }

    close(fd);
    printf("down file finish\n");

    
}


void recv_file(int c,char *filename)
{
    if(filename==NULL)
    {
        return;
    }
   int fd=open(filename,O_WRONLY|O_CREAT,0600);
   
   if(fd==-1)
   {
       send(c,"err",3,0);
       close(fd);
       return;
   }
    send(c,"ok",2,0);   
    char buff[128]={0};
    recv(c,buff,127,0);
    int filesize=atoi(buff+3);
   send(c,"ok#",3,0);
   char data[1024]={0};
   int num=0;
   int currsize=0;
   while(1)
   {
       num=recv(c,data,1024,0);
       if(num<=0)
       {
           printf("cli close\n");
           break;
       }
       currsize+=num;
       write(fd,data,num);

       if(currsize>=filesize)
       {
           break;
       }
   }
   printf("up finish\n");
   close(fd);

}

void* work_thread(void *arg)//
{
    int c=(int)arg;
    if(c<0)
    {
        pthread_exit(NULL);
    }


    while(1)
    {
        char buff[128]={0};
        int num=recv(c,buff,127,0);
        if(num<=0)
        {
            break;
        }
        char *my_argv[max_arg]={0};
        char *cmd=get_cmd(buff,my_argv);
        if(cmd==NULL)
        {
            send(c,"err",3,0);
            continue;
        }
        if(strcmp(cmd,"get")==0)
        {
            send_file(c,my_argv[1]);
                        
        }
        else if(strcmp(cmd,"up")==0)
        {
           recv_file(c,my_argv[1]);    
        }
        else
        {
            int pipefd[2];
            int n=pipe(pipefd);
            if(n==-1)
            {
                send(c,"err",3,0);
                continue;
            }



            pid_t pid=fork();
            if(pid==-1)
            {
                send(c,"err",3,0);
                continue;
            }


            if(pid==0)
            {
                dup2(pipefd[1],1);
                dup2(pipefd[1],2);

                close(pipefd[0]);

                execvp(cmd,my_argv);
                perror("not found cmd");
                exit(0);
            }

            close(pipefd[1]);
            wait(NULL);

            char read_buff[1024]={"OK#"};
            read(pipefd[0],read_buff+3,1021);
            send(c,read_buff,strlen(read_buff),0);
            close(pipefd[0]);
        }
        
        
    }
    close(c);
    printf("one client close\n");
}

void thread_start(int c)
{
    pthread_t id;
    pthread_create(&id,NULL,work_thread,(void*)c);

}
